import { useState, useEffect, useCallback } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import {
  Card,
  Button,
  Space,
  Message,
  Typography,
  Spin,
} from '@arco-design/web-react'
import {
  IconLeft,
  IconSave,
  IconCheck,
  IconPlus,
} from '@arco-design/web-react/icon'
import ReactFlow, {
  Background,
  Controls,
  MiniMap,
  addEdge,
  useNodesState,
  useEdgesState,
} from 'reactflow'
import type { Connection, Edge, Node, NodeTypes } from 'reactflow'
import 'reactflow/dist/style.css'
import { getWorkflowById, updateWorkflow, validateWorkflow } from '@/api/workflow'
import type { WorkflowDefinition, Stage } from '@/types'
import StageNode from '@/components/WorkflowEditor/StageNode'
import StepConfigPanel from '@/components/WorkflowEditor/StepConfigPanel'
import './index.css'

const { Title } = Typography

// 自定义节点类型
const nodeTypes: NodeTypes = {
  stageNode: StageNode,
}

export default function WorkflowEditor() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [workflow, setWorkflow] = useState<WorkflowDefinition | null>(null)
  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])
  const [selectedNode, setSelectedNode] = useState<Node | null>(null)

  // 加载工作流数据
  useEffect(() => {
    if (!id) return

    const loadWorkflow = async () => {
      try {
        const data = await getWorkflowById(Number(id))
        setWorkflow(data)

        // 将工作流数据转换为节点和边
        if (data.stages) {
          const flowNodes = convertStagesToNodes(data.stages)
          const flowEdges = convertStagesToEdges(data.stages)
          setNodes(flowNodes)
          setEdges(flowEdges)
        }
      } catch (error) {
        console.error('Failed to load workflow:', error)
        Message.error('加载工作流失败')
      } finally {
        setLoading(false)
      }
    }

    loadWorkflow()
  }, [id])

  // 将 Stages 转换为 ReactFlow 节点
  const convertStagesToNodes = (stages: Stage[]): Node[] => {
    return stages.map((stage, index) => ({
      id: `stage-${stage.id}`,
      type: 'stageNode',
      position: { x: 100 + index * 300, y: 100 },
      data: {
        name: stage.name,
        executionMode: stage.executionMode,
        steps: stage.steps || [],
        stageId: stage.id,
        order: stage.order,
      },
    }))
  }

  // 将 Stages 转换为 ReactFlow 边
  const convertStagesToEdges = (stages: Stage[]): Edge[] => {
    const sortedStages = [...stages].sort((a, b) => a.order - b.order)
    const edges: Edge[] = []

    for (let i = 0; i < sortedStages.length - 1; i++) {
      edges.push({
        id: `edge-${sortedStages[i].id}-${sortedStages[i + 1].id}`,
        source: `stage-${sortedStages[i].id}`,
        target: `stage-${sortedStages[i + 1].id}`,
        animated: true,
      })
    }

    return edges
  }

  // 连接节点
  const onConnect = useCallback(
    (connection: Connection) => {
      setEdges((eds) => addEdge(connection, eds))
    },
    [setEdges]
  )

  // 节点点击事件
  const onNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {
    setSelectedNode(node)
  }, [])

  // 添加新 Stage
  const handleAddStage = () => {
    const newStageId = Date.now()
    const newNode: Node = {
      id: `stage-${newStageId}`,
      type: 'stageNode',
      position: { x: 100 + nodes.length * 300, y: 100 },
      data: {
        name: `Stage ${nodes.length + 1}`,
        executionMode: 0, // Serial
        steps: [],
        stageId: newStageId,
        order: nodes.length,
      },
    }
    setNodes((nds) => [...nds, newNode])
  }

  // 验证工作流
  const handleValidate = async () => {
    if (!id) return

    try {
      await validateWorkflow(Number(id))
      Message.success('工作流配置有效')
    } catch (error) {
      console.error('Validation failed:', error)
    }
  }

  // 保存工作流
  const handleSave = async () => {
    if (!id || !workflow) return

    setSaving(true)
    try {
      // 将节点和边转换回工作流数据结构
      const stages = convertNodesToStages(nodes)

      const updatedWorkflow = {
        ...workflow,
        stages,
      }

      await updateWorkflow(Number(id), updatedWorkflow)
      Message.success('保存成功')
    } catch (error) {
      console.error('Failed to save workflow:', error)
    } finally {
      setSaving(false)
    }
  }

  // 将节点转换回 Stages
  const convertNodesToStages = (nodes: Node[]): Stage[] => {
    return nodes.map((node, index) => ({
      id: node.data.stageId,
      workflowDefinitionId: Number(id),
      name: node.data.name,
      order: index,
      executionMode: node.data.executionMode,
      steps: node.data.steps,
    }))
  }

  if (loading) {
    return (
      <div className="workflow-editor">
        <Card>
          <div style={{ textAlign: 'center', padding: '100px 0' }}>
            <Spin size={40} />
          </div>
        </Card>
      </div>
    )
  }

  if (!workflow) {
    return (
      <div className="workflow-editor">
        <Card>
          <div style={{ textAlign: 'center', padding: '100px 0' }}>
            <Typography.Text type="secondary">工作流不存在</Typography.Text>
          </div>
        </Card>
      </div>
    )
  }

  return (
    <div className="workflow-editor">
      <div className="workflow-editor-header">
        <Space>
          <Button
            type="text"
            icon={<IconLeft />}
            onClick={() => navigate('/workflow')}
          >
            返回
          </Button>
          <Title heading={4} style={{ margin: 0 }}>
            编辑工作流: {workflow.name}
          </Title>
        </Space>
        <Space>
          <Button icon={<IconPlus />} onClick={handleAddStage}>
            添加 Stage
          </Button>
          <Button icon={<IconCheck />} onClick={handleValidate}>
            验证
          </Button>
          <Button
            type="primary"
            icon={<IconSave />}
            loading={saving}
            onClick={handleSave}
          >
            保存
          </Button>
        </Space>
      </div>

      <div className="workflow-editor-content">
        <div className="workflow-canvas">
          <ReactFlow
            nodes={nodes}
            edges={edges}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            onNodeClick={onNodeClick}
            nodeTypes={nodeTypes}
            fitView
          >
            <Background />
            <Controls />
            <MiniMap />
          </ReactFlow>
        </div>

        {selectedNode && (
          <div className="workflow-config-panel">
            <StepConfigPanel
              node={selectedNode}
              onUpdate={(updatedNode) => {
                setNodes((nds) =>
                  nds.map((n) => (n.id === updatedNode.id ? updatedNode : n))
                )
                setSelectedNode(updatedNode)
              }}
              onClose={() => setSelectedNode(null)}
            />
          </div>
        )}
      </div>
    </div>
  )
}
